package definite.Guide.Book.JViewPort;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ActionMap;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.InputMap;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JViewport;
import javax.swing.KeyStroke;

public class MoveSample {

	// define field for action key
	private static final String UP = "up";
	private static final String DOWN = "down";
	private static final String LEFT = "left";
	private static final String RIGHT = "right";
	private static final String PG_UP = "pgUP";
	private static final String PG_DOWN = "pgDown";
	private static final String SHIFT_PG_UP = "shiftPgUp";
	private static final String SHIFT_PG_DOWN = "shiftPgDown";

	// define constain for class MoveAction
	// direction
	private static final int INCREASE = 0;
	private static final int DECREASE = 1;
	// axis
	private static final int X_AXIS = 0;
	private static final int Y_AXIS = 1;
	// type
	private static final int UNIT = 0;
	private static final int BLOCK = 1;

	static class MoveAction extends AbstractAction {

		private JViewport view;
		private int direction;
		private int axis;
		private int type;

		public MoveAction(JViewport view, int direction, int axis, int type) {
			if (view == null)
				throw new IllegalArgumentException(
						"The ViewPort must be declared");
			else {
				this.view = view;
				this.direction = direction;
				this.axis = axis;
				this.type = type;
			}// end else
		}

		@Override
		public void actionPerformed(ActionEvent e) {
			int horMoveSize = 0;
			int verMoveSize = 0;
			Dimension extendSize = view.getExtentSize();
			if (axis == X_AXIS) {
				if (type == UNIT)
					horMoveSize += 1;
				else if (type == BLOCK)
					horMoveSize = extendSize.width;
			} else if (axis == Y_AXIS) {
				if (type == UNIT)
					verMoveSize += 1;
				else if (type == BLOCK)
					verMoveSize = extendSize.height;
			}

			if (direction == DECREASE) {
				horMoveSize = -horMoveSize;
				verMoveSize = -verMoveSize;
			}

			Point origin = view.getViewPosition();
			origin.x += horMoveSize;
			origin.y += verMoveSize;
			view.setViewPosition(origin);
		}

	}

	public static void main(String[] args) {
		Runnable r = new Runnable() {

			@Override
			public void run() {
				JFrame.setDefaultLookAndFeelDecorated(true);
				JFrame frame = new JFrame("JViewPort Sample");
				frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
				Icon icon = new ImageIcon("RedBall.gif");
				JLabel label = new JLabel(icon);
				JViewport viewport = new JViewport();
				viewport.setView(label);

				InputMap inputMap =
					viewport.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
				ActionMap actionMap = viewport.getActionMap();

				// up key move view up unit
				Action upKeyAction =
					new MoveAction(viewport, DECREASE, Y_AXIS, UNIT);
				KeyStroke upKey =
					KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, false);
				inputMap.put(upKey, UP);
				actionMap.put(UP, upKeyAction);

				// down key move view down unit
				Action downKeyAction =
					new MoveAction(viewport, INCREASE, Y_AXIS, UNIT);
				KeyStroke downKey =
					KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0, false);
				inputMap.put(downKey, DOWN);
				actionMap.put(DOWN, downKeyAction);

				// left key move view left unit
				Action leftAction =
					new MoveAction(viewport, INCREASE, X_AXIS, UNIT);
				KeyStroke leftKey =
					KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0, false);
				inputMap.put(leftKey, LEFT);
				actionMap.put(LEFT, leftAction);

				// pgUp key move block
				Action pgUpKeyAction =
					new MoveAction(viewport, DECREASE, Y_AXIS, BLOCK);
				KeyStroke pgUpKey = KeyStroke.getKeyStroke("PAGE_UP");
				inputMap.put(pgUpKey, "pgUp");
				actionMap.put("pgUp", pgUpKeyAction);

				// PgDn key moves view down block
				Action pgDnKeyAction =
					new MoveAction(viewport, INCREASE, Y_AXIS, BLOCK);
				KeyStroke pgDnKey = KeyStroke.getKeyStroke("PAGE_DOWN");
				inputMap.put(pgDnKey, "pgDn");
				actionMap.put("pgDn", pgDnKeyAction);

				JScrollPane p =
					new JScrollPane(viewport,
							JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
							JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
				frame.add(p, BorderLayout.CENTER);
				frame.setLocationRelativeTo(null);
				frame.setSize(300, 200);
				frame.setVisible(true);
			}
		};

		EventQueue.invokeLater(r);
	}

}
